import fs from 'fs';
import forge from 'node-forge';
import path from 'path';

/**
 * 证书管理器
 * 负责SSL证书的生成、缓存和管理
 */
export class CertManager {
  constructor() {
    this.certs = new Map();
    this.rootKey = null;
    this.rootCert = null;
  }

  /**
   * 生成根证书
   */
  async generateRootCert() {
    const certPath = path.join(process.cwd(), 'certs', 'root-cert.pem');
    const keyPath = path.join(process.cwd(), 'certs', 'root-key.pem');

    // 检查是否已存在根证书
    if (fs.existsSync(certPath) && fs.existsSync(keyPath)) {
      console.log('📋 使用现有根证书');
      this.rootCert = fs.readFileSync(certPath, 'utf8');
      this.rootKey = fs.readFileSync(keyPath, 'utf8');
      return;
    }

    console.log('🔐 生成新的根证书...');

    // 确保certs目录存在
    const certsDir = path.join(process.cwd(), 'certs');
    if (!fs.existsSync(certsDir)) {
      fs.mkdirSync(certsDir, { recursive: true });
    }

    // 生成根证书密钥对
    const keys = forge.pki.rsa.generateKeyPair(2048);
    
    // 创建根证书
    const rootCert = forge.pki.createCertificate();
    rootCert.publicKey = keys.publicKey;
    rootCert.serialNumber = '01';
    rootCert.validity.notBefore = new Date();
    rootCert.validity.notAfter = new Date();
    rootCert.validity.notAfter.setFullYear(rootCert.validity.notBefore.getFullYear() + 10);

    const attrs = [
      { name: 'commonName', value: 'Network Firewall Proxy Root CA' },
      { name: 'countryName', value: 'CN' },
      { shortName: 'ST', value: 'Beijing' },
      { name: 'localityName', value: 'Beijing' },
      { name: 'organizationName', value: 'Network Firewall Proxy' },
      { shortName: 'OU', value: 'IT Department' }
    ];

    rootCert.setSubject(attrs);
    rootCert.setIssuer(attrs);
    
    rootCert.setExtensions([
      { name: 'basicConstraints', cA: true },
      { name: 'keyUsage', keyCertSign: true, digitalSignature: true, keyEncipherment: true }
    ]);

    // 自签名
    rootCert.sign(keys.privateKey, forge.md.sha256.create());

    // 转换为PEM格式
    this.rootCert = forge.pki.certificateToPem(rootCert);
    this.rootKey = forge.pki.privateKeyToPem(keys.privateKey);

    // 保存证书
    fs.writeFileSync(certPath, this.rootCert);
    fs.writeFileSync(keyPath, this.rootKey);

    console.log('✅ 根证书生成完成');
    console.log(`📁 证书保存路径: ${certPath}`);
    console.log(`🔑 私钥保存路径: ${keyPath}`);
  }

  /**
   * 为指定主机名生成证书
   */
  async generateCertForHost(hostname) {
    console.log(`🔐 为 ${hostname} 生成证书...`);

    try {
      // 解析根证书和密钥
      const rootCert = forge.pki.certificateFromPem(this.rootCert);
      const rootKey = forge.pki.privateKeyFromPem(this.rootKey);

      // 生成新的密钥对
      const keys = forge.pki.rsa.generateKeyPair(2048);

      // 创建证书
      const cert = forge.pki.createCertificate();
      cert.publicKey = keys.publicKey;
      cert.serialNumber = Math.random().toString().substring(2);
      cert.validity.notBefore = new Date();
      cert.validity.notAfter = new Date();
      cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);

      // 设置主题（被证明的实体）
      const attrs = [
        { name: 'commonName', value: hostname },
        { name: 'countryName', value: 'CN' },
        { shortName: 'ST', value: 'Beijing' },
        { name: 'localityName', value: 'Beijing' },
        { name: 'organizationName', value: 'Network Firewall Proxy' },
        { shortName: 'OU', value: 'IT Department' }
      ];

      cert.setSubject(attrs);
      cert.setIssuer(rootCert.subject.attributes);

      // 设置扩展
      cert.setExtensions([
        { name: 'basicConstraints', cA: false },
        { name: 'keyUsage', digitalSignature: true, keyEncipherment: true },
        { name: 'extKeyUsage', serverAuth: true, clientAuth: true },
        {
          name: 'subjectAltName',
          altNames: [
            { type: 2, value: hostname },
            { type: 2, value: `*.${hostname}` }
          ]
        }
      ]);

      // 用根证书签名
      cert.sign(rootKey, forge.md.sha256.create());

      // 转换为PEM格式
      const certPem = forge.pki.certificateToPem(cert);
      const keyPem = forge.pki.privateKeyToPem(keys.privateKey);

      const certData = {
        cert: certPem,
        key: keyPem,
        hostname: hostname,
        createdAt: Date.now()
      };

      // 缓存证书
      this.certs.set(hostname, certData);

      console.log(`✅ ${hostname} 证书生成完成`);
      return certData;

    } catch (error) {
      console.error(`❌ 生成 ${hostname} 证书失败:`, error.message);
      throw error;
    }
  }

  /**
   * 确保指定主机名有可用的证书
   */
  async ensureCertForHost(hostname) {
    if (!this.certs.has(hostname)) {
      await this.generateCertForHost(hostname);
    }
    return this.certs.get(hostname);
  }

  /**
   * 获取SNI证书回调函数
   */
  getSNICertCallback() {
    return async (servername, callback) => {
      try {
        const certData = await this.ensureCertForHost(servername);
        const ctx = require('tls').createSecureContext({
          key: certData.key,
          cert: certData.cert
        });
        callback(null, ctx);
      } catch (error) {
        console.error(`❌ SNI证书回调失败 (${servername}):`, error.message);
        callback(error);
      }
    };
  }

  /**
   * 清理证书缓存
   */
  clearCache() {
    this.certs.clear();
  }

  /**
   * 获取证书统计信息
   */
  getStats() {
    return {
      cachedCerts: this.certs.size,
      hasRootCert: !!(this.rootCert && this.rootKey),
      certList: Array.from(this.certs.keys())
    };
  }
} 